package it.yuzuojian.com.task;

import com.pngencoder.PngEncoder;
import it.yuzuojian.com.util.SystemUtil;
import lombok.SneakyThrows;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Encoder;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.websocket.Session;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.logging.Logger;


@Component
public class ScreenCaptureTask implements Runnable {
    private Session session;

    private Robot robot = new Robot();

    private SystemUtil systemUtil = new SystemUtil();

    public Session getSession() {
        return session;
    }

    private Logger logger = Logger.getLogger("WebSocketServerController");

    public void setSession(Session session) {
        this.session = session;
    }

    public ScreenCaptureTask(Session session) throws AWTException {
        this.session = session;
    }

    public ScreenCaptureTask() throws AWTException {
    }

    @SneakyThrows
    @Override
    public void run() {
        String id = session.getId();
        while (session.isOpen()) {
            long start = System.currentTimeMillis();
            Dimension d = new Dimension(Toolkit.getDefaultToolkit().getScreenSize());
            int width = (int) d.getWidth();
            int height = (int) d.getHeight();
            BufferedImage image = robot.createScreenCapture(new Rectangle(0, 0, width, height));
            BASE64Encoder base64Encoder = new BASE64Encoder();
            /*ImageIO.write(image, "jpeg",os);这个拉跨*/
            byte[] bytes = new PngEncoder()//目前这个速度最快
                    .withBufferedImage(image)
                    .withCompressionLevel(1)
                    .toBytes();
            //bytes = compressPicByQuality(bytes,0.01f);
            StringBuffer stringBuffer = new StringBuffer();
            SystemUtil.Cursor currentCursor = systemUtil.getCurrentCursor();//获取当前系统鼠标样式
            //System.out.println("currentCursor.getCode() = " + currentCursor.getCode());
            if (currentCursor != null) {
                stringBuffer.append(currentCursor.getCode() + "*****currentCursor*******");
            } else {
                stringBuffer.append("-1" + "*****currentCursor*******");
            }

            String json = base64Encoder.encode(bytes);
            stringBuffer.append(json);
            if (session.isOpen()) {
                session.getBasicRemote().sendText(stringBuffer.toString());
            } else {
                logger.info("{} 已断开..." + id);
            }

            long end = System.currentTimeMillis();
            System.out.println("耗时： = " + (end-start)); //有个大问题，当屏幕图片简单时，一次截图60ms左右，1秒 16帧，有点不流畅，但是够用， 但是当屏幕色彩多的时候，300ms一次截图，1s4帧还不到，根本无法流畅使用

        }
    }


    /**
     * 压缩图片（通过降低图片质量）
     *
     * @param quality 图片质量（0-1）
     * @return byte[]
     * 压缩后的图片（jpg）
     * @throws
     * @explain 压缩图片, 通过压缩图片质量，保持原图大小
     */
    public static byte[] compressPicByQuality(byte[] imgByte, float quality) {
        byte[] imgBytes = null;
        try {
            ByteArrayInputStream byteInput = new ByteArrayInputStream(imgByte);
            BufferedImage image = ImageIO.read(byteInput);

            // 如果图片空，返回空
            if (image == null) {
                return null;
            }
            // 得到指定Format图片的writer（迭代器）
            Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("jpeg");
            // 得到writer
            ImageWriter writer = (ImageWriter) iter.next();
            // 得到指定writer的输出参数设置(ImageWriteParam )
            ImageWriteParam iwp = writer.getDefaultWriteParam();
            // 设置可否压缩
            iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
            // 设置压缩质量参数
            iwp.setCompressionQuality(quality);

            iwp.setProgressiveMode(ImageWriteParam.MODE_DISABLED);

            ColorModel colorModel = ColorModel.getRGBdefault();
            // 指定压缩时使用的色彩模式
            iwp.setDestinationType(
                    new javax.imageio.ImageTypeSpecifier(colorModel, colorModel.createCompatibleSampleModel(16, 16)));

            // 开始打包图片，写入byte[]
            // 取得内存输出流
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            IIOImage iIamge = new IIOImage(image, null, null);

            // 此处因为ImageWriter中用来接收write信息的output要求必须是ImageOutput
            // 通过ImageIo中的静态方法，得到byteArrayOutputStream的ImageOutput
            writer.setOutput(ImageIO.createImageOutputStream(byteArrayOutputStream));
            writer.write(null, iIamge, iwp);
            imgBytes = byteArrayOutputStream.toByteArray();
        } catch (IOException e) {
            System.out.println("write errro");
            e.printStackTrace();
        }
        return imgBytes;
    }

}
